package com.hlkj.pay.app.merchant.ext.impl.hnapay.utils;

import com.alibaba.fastjson.JSONObject;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.ext.impl.hnapay.dto.HnapayConfig;
import com.hnapay.keyAlgorithm.sm2.SM2Algorithms;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author OYYL
 * @version V1.0
 * @Description: 收款工具类
 * @Title: RecepitUtil
 * @Package com.hnapay.recepitdemo.utils
 * @date 2017/8/18 15:39
 **/
public class RecepitUtil
{
	// 签名字段
	public static Map<String, String[]> signField = new HashMap<>();

	// 验签字段
	public static Map<String, String[]> verifyField = new HashMap<>();

	/**
	 * 初始化静态加载块
	 */
	static
	{
		// 以下为验签信息
		verifyField.put("WS01", new String[] { "tranCode", "version", "merId", "merOrderNum", "tranAmt", "submitTime", "qrCodeUrl", "hnapayOrderId", "resultCode", "charset", "signType" });
		verifyField.put("ITA10", new String[] {"version", "tranCode", "merOrderId", "merId", "charset", "signType", "resultCode","errorCode", "hnapayOrderId","payInfo"});
		verifyField.put("EXP09", new String[] {"version", "tranCode", "merOrderId", "merId", "charset", "signType", "resultCode","errorCode", "hnapayOrderId", "orgMerOrderId", "tranAmt", "refundAmt", "orderStatus"});
	}

	/**
	 * 签名接口
	 *
	 * @param params
	 * @return
	 */
	public static String sign(String smPrivateKey, Map<String, String> params) throws Exception
	{
		if (null == params)
			throw new IllegalArgumentException("报文信息参数无效！");
		String needSignMsg = getSm2SignContent(params);
		byte[] b = SM2Algorithms.getSignByte(smPrivateKey, needSignMsg);
		return HnapayBase64.encode2String(b);
	}

	public static boolean verify(JSONObject response, HnapayConfig payConfig, String signMsgStr) throws Exception {
		Map<String, String> params = response.toJavaObject(Map.class);
		return verify(params.get("tranCode"), params, payConfig.getHnaM2PublicKey(), signMsgStr);
	}

	/**
	 * 验签接口
	 *
	 * @param tranType
	 * @param params
	 * @return
	 */
	public static boolean verify(String tranType, Map<String, String> params, String m2PublicKey, String signMsgStr) throws Exception
	{
		if (null == params)
			throw new IllegalArgumentException("报文信息参数无效！");
		// 执行验签操作
		byte[] signMsgBytes = HnapayBase64.decode2Byte(signMsgStr);
		String needVerifyMsg = genSm2VerifyData(tranType, params);
		return SM2Algorithms.verify(m2PublicKey, needVerifyMsg, signMsgBytes);
	}

	/**
	 * 生成Sm2验签明文串
	 *
	 * @param params
	 * @return
	 */
	private static String genSm2VerifyData(String tranType, Map<String, String> params)
	{
		StringBuilder sb = new StringBuilder();
		sb.append("");
		for (int i = 0; i < verifyField.get(tranType).length; i++)
		{
			sb.append(verifyField.get(tranType)[i]);
			sb.append("=");
			sb.append("[" + params.get(verifyField.get(tranType)[i]) + "]");
		}
		String needVerifyMsg = sb.toString();
		System.out.println("Sm2 needVerifyMsg:" + needVerifyMsg);
		return needVerifyMsg;
	}

	/**
	 * 加密 ，对敏感信息的加密 ，签名前需要对敏感信息加密
	 *
	 * @param params   加密字段
	 * @return 密文
	 */
	public static String encrpt(Map<String, String> params, String publicKey) throws IllegalArgumentException {
		if (null == params)
			throw new IllegalArgumentException("参数无效！");
		String plainData = JsonUtils.toJsonString(params);
		try {
			byte[] cipherBytes = SM2Algorithms.encryptByPublicKey(plainData.getBytes("UTF-8"), publicKey);
			// 使用Java标准库的Base64编码
			return Base64.getEncoder().encodeToString(cipherBytes);
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}

	}

	/**
	 * 生成m2签名明文串
	 * @param params
	 * @return
	 */
	private static String getSm2SignContent(Map<String,String> params) throws Exception{
		Set<String> keys = params.keySet();
		StringBuilder sb = new StringBuilder();
		sb.append("");
		for (String key : keys) {
			sb.append(key);
			sb.append("=[");
			sb.append(params.get(key));
			sb.append("]");
		}
		String needSignMsg = sb.toString();
		System.out.println("Sm2 needSignMsg:"+needSignMsg);
		return needSignMsg;
	}
}
